#!/bin/sh
#
# Run lexer tests
#
# Copyright © 2017 Eric Bavier <bavier@member.fsf.org>
# License: GPLv3+
#####

output=tests/lexer/output
log=test-lexer.log
rm -f $log
ret=0

run_test ()
{
    base=`basename "$1" | sed 's/\..*$//'`
    echo "$base: " >>$log
    tmp=test-lexer-$base.tmp
    timeout 5s ./lexer < "$1" >$tmp 2>/dev/null
    if diff -Nau $output/$base.out $tmp >>$log; then
	printf "$base: PASS\n\n" >>$log
    else
	printf "$base: FAIL\n\n" >>$log
	ret=1
    fi
    rm $tmp
}

# Check some simple inputs

run_test tests/input/keywords.in
run_test tests/input/assign.in
run_test tests/input/flip-flop.in
run_test tests/input/choice.in
run_test tests/input/big-choice.in
run_test tests/input/else.in
run_test tests/input/print.in
run_test tests/input/simple.c
run_test tests/input/test-case-1.in
run_test tests/input/test-case-2.in
run_test tests/input/test-case-3.in
run_test tests/input/test-case-4.in
run_test tests/input/count.in
run_test tests/input/100_doors.in
run_test tests/input/negative.in
run_test tests/input/deep.in
run_test tests/input/gcd.in
run_test tests/input/factorial.in
run_test tests/input/fibonacci.in
run_test tests/input/fizzbuzz.in
run_test tests/input/99bottles.in
run_test tests/input/primes.in
run_test tests/input/mandelbrot.in

# Check expected error/diagnostic outputs

tmp=test-lexer-fail-empty-char.tmp
echo "empty character:" >>$log
timeout 1s ./lexer >$tmp 2>/dev/null <<EOF
char foo = '';
EOF
if grep -q -i "unexpected" $tmp; then
    printf "empty character: PASS\n\n" >>$log
else
    cat $tmp >>$log
    printf "empty character: FAIL\n\n" >>$log
    ret=1
fi
rm $tmp

tmp=test-lexer-fail-escape-sequence.tmp
echo "escape sequence:" >>$log
timeout 1s ./lexer >$tmp 2>/dev/null <<EOF
char foo = '\r';
EOF
if grep -q -i "unknown escape sequence" $tmp; then
    printf "escape sequence: PASS\n\n" >>$log
else
    cat $tmp >>$log
    printf "escape sequence: FAIL\n\n" >>$log
    ret=1
fi
rm $tmp

tmp=test-lexer-fail-multi-char.tmp
echo "multi-character constant:" >>$log
timeout 1s ./lexer >$tmp 2>/dev/null <<EOF
char foo = 'ab';
EOF
if grep -q -i "unexpected" $tmp; then
    printf "multi-character constant: PASS\n\n" >>$log
else
    cat $tmp >>$log
    printf "multi-character constant: FAIL\n\n" >>$log
    ret=1
fi
rm $tmp

tmp=test-lexer-fail-eof-comment.tmp
echo "eof in comment:" >>$log
timeout 1s ./lexer >$tmp 2>/dev/null <<EOF
/* This comment is not terminated
EOF
if grep -q -i "end-of-file in comment" $tmp; then
    printf "eof in comment: PASS\n\n" >>$log
else
    cat $tmp >>$log
    printf "eof in comment: FAIL\n\n" >>$log
    ret=1
fi
rm $tmp

tmp=test-lexer-fail-eof-string.tmp
echo "eof in string:" >>$log
timeout 1s ./lexer >$tmp 2>/dev/null <<EOF
char * foo = "Hello, world\
EOF
if grep -q -i "end-of-file in string" $tmp; then
    printf "eof in string: PASS\n\n" >>$log
else
    cat $tmp >>$log
    printf "eof in string: FAIL\n\n" >>$log
    ret=1
fi
rm $tmp

tmp=test-lexer-fail-eol-string.tmp
echo "eol in string:" >>$log
timeout 1s ./lexer >$tmp 2>/dev/null <<EOF
char * foo = "Hello,
 world!";
EOF
if grep -q -i "end-of-line in string" $tmp; then
    printf "eol in string: PASS\n\n" >>$log
else
    cat $tmp >>$log
    printf "eol in string: FAIL\n\n" >>$log
    ret=1
fi
rm $tmp

tmp=test-lexer-fail-char.tmp
echo "unrecognized character:" >>$log
timeout 1s ./lexer >$tmp 2>/dev/null <<EOF
int foo @ 1;
EOF
if grep -q -i "character.*not recognized" $tmp; then
    printf "unrecognized character: PASS\n\n" >>$log
else
    chat $tmp >>$log
    printf "unrecognized character: FAIL\n\n" >>$log
    ret=1
fi
rm $tmp

tmp=test-lexer-fail-invalid-num.tmp
echo "invalid number:" >>$log
timeout 1s ./lexer >$tmp 2>/dev/null <<EOF
int foo = 123abc;
EOF
if grep -q -i "invalid num" $tmp; then
    printf "invalid number: PASS\n\n" >>$log
else
    cat $tmp >>$log
    printf "invalid number: FAIL\n\n" >>$log
    ret=1
fi
rm $tmp

exit $ret
